let _Vue = null
class Store {
  constructor (options) {
    // 解构传入参数 
    const {
      state = {},
      getters = {},
      mutations = {},
      actions = {}
    } = options
    // 将state转为响应式属性
    this.state = _Vue.observable(state)
    this.getters = Object.create(null)
    // 将getters转换为getter存储起来
    Object.keys(getters).forEach(key => {
      Object.defineProperty(this.getters, key, {
        // 访问getters时将state参数传入
        get: () => getters[key](state)
      })
    })
    // 存储mutations和action 作为私有属性
    this._mutations = mutations
    this._actions = actions
  }

  // 调用mutation的方法 
  commit (type, payload) {
    this._mutations[type](this.state, payload)
  }

  // 调用 actions 的方法
  dispatch (type, payload) {
    this._actions[type](this, payload)
  }
}

// install函数 接收vue构造函数
function install (Vue) {
  _Vue = Vue
  // 使用混入 mixin 将store注入到实例中
  _Vue.mixin({
    beforeCreate () {
      // this => Vue实例
      if (this.$options.store) {
        _Vue.prototype.$store = this.$options.store
      }
    }
  })
}

export default {
  Store,
  install
}
